#include <string>
#include <iostream>
#include <vector>

#include "memoria.h"
#include "registradores.h"
#include "IF.h"
#include "ID.h"
#include "EXEC.h"
#include "estruturas.h"
#include "WB.h"


using namespace std;
memoria adicionaMem(char* nome){
    FILE *fp;
    fp = fopen(nome, "r+");
    memoria mem;
    char *linha = (char*)malloc(BUFSIZ*sizeof(char));
    while(!feof(fp)){
        linha = fgets(linha,BUFSIZ,fp);
        if(linha!=NULL){
            linha = strtok(linha, "\n");
            mem.insert(linha);
        }
    }
    fclose(fp);
    return mem;
}

void printReg(reg A){
    cout << A.campos.b15;
    cout << A.campos.b14;
    cout << A.campos.b13;
    cout << A.campos.b12;
    cout << A.campos.b11;
    cout << A.campos.b10;
    cout << A.campos.b9;
    cout << A.campos.b8;
    cout << A.campos.b7;
    cout << A.campos.b6;
    cout << A.campos.b5;
    cout << A.campos.b4;
    cout << A.campos.b3;
    cout << A.campos.b2;
    cout << A.campos.b1;
    cout << A.campos.b0 << endl;
}

int main(int argc, char *argv[]) {

    registradores* regs = new registradores();

    memoria mem;  

    /* leitura de arquivo
    char* nome = (char*)malloc(BUFSIZ*sizeof(char));
    nome = "entrada.txt";
    mem = adicionaMem(nome);
    */

    
    mem.insert("zeros rt0");//rt0 = 0
    mem.insert("zeros rt1");//rt1 = 0
    mem.insert("addi rt0, rt0, 2");//rt0 = 2
    mem.insert("addi rt1, rt1, -4");//rt1 = 3
    mem.insert("add rt4, rt0, rt1");//rt4 = 2 + 3 = 5
    //mem.insert("j 7");//pula para a ultima instrucao
    //mem.insert("add rt4, rt4, rt1");//nao faz nada
    //mem.insert("add rt4, rt4, rt1");//rt4 = 5 + 3 = 8
    //mem.insert("sub rt4, rt4, rt0");//rt4 = 8 - 2 = 6


    IF* iF = new IF(&mem);
    ID* id = new ID();
    EXEC* exec = new EXEC(regs, iF);
    WB* wb = new WB(regs, exec);
    while(iF->getPC()< mem.size()){
        iF->escolhe();
        id->identifica(iF->getBuffer());
        exec->executa(id->getBuffer());
        wb->executa(exec->getBuffer());
    }

    //cout << regs->GetR0().valor << " - " << regs->GetR1().valor << endl ;
    cout << "Valor do registrador r4: " << regs->GetR4().valor << endl;
    printReg(regs->GetR0());
    printReg(regs->GetR1());
    printReg(regs->GetR4());
    
    return EXIT_SUCCESS;
}